#include "verema_graphicsscene.h"
#include "visualwidget.h"

#include <QtGui/QGraphicsSceneMouseEvent>
#include <QtGui/QPen>
#include <QtGui/QBrush>
#include <QtCore/QLineF>
#include <QtCore/QRectF>
#include <QtGui/QColor>
#include <QtGui/QGraphicsItem>

#include <iostream>

namespace verema {

void GraphicsScene::addRectItem(QRectF rect_item, int id, bool used)
{
    QGraphicsRectItem *rect_temp = new QGraphicsRectItem(rect_item);


    if(!used)
    {
        QBrush brush( QColor(200,200,250,150) ,  Qt::SolidPattern);
        QPen pen(Qt::cyan, 0);
        pen.setStyle(Qt::SolidLine);
        rect_temp->setPen(pen);
        rect_temp->setBrush(brush);
    }
    else
    {
        QBrush brush( QColor(0, 0, 255, 150) ,  Qt::Dense5Pattern);
        QPen pen(Qt::cyan, 0);
        pen.setStyle(Qt::SolidLine);
        rect_temp->setPen(pen);
        rect_temp->setBrush(brush);
    }



    rect_item_list.push_back(rect_temp, id, used);
    addItem(rect_temp);
}

void GraphicsScene::remRectItem(QPointF point)
{
    if( select_Rect_Item(point) != 0)
    {
        rect_item_list.remove(selected_Item);
        removeItem(selected_Item);
    }
}

void GraphicsScene::rem_Rect_by_Id(int id)
{
    removeItem(rect_item_list.at(id));
    rect_item_list.remove(id);
}

void GraphicsScene::changeRect(QRectF new_rect)
{
    if (selected_Item != 0)
    {
        selected_Item->setRect(new_rect);
    }
}

int GraphicsScene::countRect()
{
    return(rect_item_list.count());
}

void GraphicsScene::remAllRectItems()
{
    if(countRect() > 0)
    {
        rect_item_list.clear();

        QList<QGraphicsItem *> list = items();
        QList<QGraphicsItem *>::Iterator it = list.begin();
        for (; it != list.end(); ++it)
        {
            if ( *it )
            {
                if((*it) != get_background() )delete *it;
            }
        }
    }
    selected_Item = 0;
}


QRectF GraphicsScene::get_selected_Item()
{
    if(selected_Item != 0) return(selected_Item->sceneBoundingRect());
    return(QRectF(0,0,0,0));
}
/*
int GraphicsScene::get_selected_Item_id()
{
    return(rect_item_list.id(selected_Item));
}*/

void GraphicsScene::reset_Selection()
{
    if(selected_Item != 0)
    {


        int id = rect_item_list.id(selected_Item);
        if(!rect_item_list.used(id))
        {
            QBrush brush( QColor(200,200,255,150) ,  Qt::SolidPattern);
            QPen pen(Qt::cyan,0 );
            pen.setStyle(Qt::SolidLine);
            selected_Item->setPen(pen);
            selected_Item->setBrush(brush);
        }
        else
        {
            QBrush brush( QColor(0, 0, 255, 150) ,  Qt::Dense5Pattern);
            QPen pen(Qt::cyan,0 );
            pen.setStyle(Qt::SolidLine);
            selected_Item->setPen(pen);
            selected_Item->setBrush(brush);
        }
        selected_Item = 0;
    }
}

QGraphicsRectItem* GraphicsScene::select_Rect_Item(QPointF point)
{
    reset_Selection();
    if(itemAt(point.x(), point.y()) != 0 && itemAt(point.x(), point.y()) != gpi_background)
    {
        //select Item from scene
        selected_Item = (QGraphicsRectItem*)itemAt(point.x(), point.y());

        for (QList<QGraphicsRectItem *>::Iterator it = rect_item_list.begin(); it != rect_item_list.end(); ++it)
        {
            if ( *it == selected_Item)
            {
               //redraw Item in selection colors
                QPen pen(Qt::yellow,0 );
                pen.setStyle(Qt::SolidLine);
                QBrush brush( QColor(255,255,200,150) ,  Qt::SolidPattern);
                selected_Item->setPen(pen);
                selected_Item->setBrush(brush);
                break;
            }
        }
        //return the rect
        return(selected_Item);
    }
    return(NULL);
}

void GraphicsScene::select_Rect_by_Id(int id)
{
    reset_Selection();
    selected_Item = rect_item_list.at(id);
    if(selected_Item != 0)
    {
        QPen pen(Qt::yellow,0 );
        pen.setStyle(Qt::SolidLine);
        QBrush brush( QColor(255,255,200,150) ,  Qt::SolidPattern);
        selected_Item->setPen(pen);
        selected_Item->setBrush(brush);
    }
}

void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{


    if (mouseEvent->button() == Qt::LeftButton)
    {
        left_mousebutton_down = true;

        if( selected_Item != 0)
        {
            if(editingMode == SELECT && selected_Item == /*(QGraphicsRectItem*)*/itemAt(mouseEvent->scenePos().x(), mouseEvent->scenePos().y()))
            {
                editingMode = MOVE_FRAME;
                move_point = mouseEvent->scenePos();
            }
        }
        else
        {
            reset_Selection();
        }

        if(editingMode == CREATE_RECT_FRAME)
        {
            rect = new QGraphicsRectItem(QRectF(mouseEvent->scenePos().toPoint(), mouseEvent->scenePos().toPoint()));
            QPen pen(Qt::green, 2);
            pen.setStyle(Qt::DotLine);
            rect->setPen(pen);
            addItem(rect);
        }

        if(editingMode == DELETE)
        {
            select_Rect_Item(mouseEvent->scenePos());
        }

    }
}

void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{

    emit moveinView( (int)mouseEvent->scenePos().x(), (int)mouseEvent->scenePos().y() );
    /*std::string temp_string;
    std::string temp_string2;
    std::stringstream temp_ss1;
    temp_ss1 << (int)mouseEvent->scenePos().x();
    temp_ss1 >> temp_string;
    std::stringstream temp_ss2;
    temp_ss2 << (int)mouseEvent->scenePos().y();
    temp_ss2 >> temp_string2;

    temp_string = temp_string + " ";
    temp_string = temp_string + temp_string2;

    QString temp(temp_string.c_str());*/

    //if(status_bar != 0) status_bar->showMessage(temp);
    if(left_mousebutton_down == true)
    {
        if(editingMode == CREATE_RECT_FRAME)
        {
            if(rect != 0)
            {
                QRectF newRect( rect->rect().topLeft(), mouseEvent->scenePos().toPoint());
                rect->setRect(newRect);
            }
        }
        if(editingMode == MOVE_FRAME)
        {
            QRectF newRect( mouseEvent->scenePos() - move_point + selected_Item->rect().topLeft(), mouseEvent->scenePos() - move_point + selected_Item->rect().bottomRight());
            selected_Item->setRect(newRect);
            move_point = mouseEvent->scenePos();
        }
    }
}

void GraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
    last_mouseup_pos = mouseEvent->scenePos();
    if (mouseEvent->button() == Qt::LeftButton)
    {
        left_mousebutton_down = false;
        if(editingMode == CREATE_RECT_FRAME)
        {
            addRectItem(rect->rect(),0, false);
            select_Rect_by_Id(0);
            emit rectAdded(rect->rect());
            removeItem(rect);
        }
        else if(editingMode == SELECT)
        {
            select_Rect_Item(mouseEvent->scenePos());
        }
        else if( editingMode == DELETE)
        {
            if(selected_Item != 0)
            {
                //std::cout << "mouseReleaseEvent DELETE: getSelectedId() = " << getSelectedId() << std::endl;
                int sel_id = getSelectedId();
                rem_Rect_by_Id(  sel_id );
                emit rectRemoved( sel_id );

                reset_Selection();
                //selected_Item = 0;
            }
        }
        else if( editingMode == MOVE_FRAME)
        {
            editingMode = SELECT;
            emit rectChanged(selected_Item->rect()/*, getSelectedId()*/);
        }
        emit mouseReleased();
    }
    else if( mouseEvent->button() == Qt::RightButton)
    {
        if( editingMode == SELECT)
        {
            if(itemAt(mouseEvent->scenePos()) != 0 && itemAt(mouseEvent->scenePos()) != gpi_background)
            {
                if( rect_item_list.used( rect_item_list.id( (QGraphicsRectItem*)itemAt(mouseEvent->scenePos()) ) ) == true)
                {
                    use->setChecked(true);
                    unuse->setChecked(false);
                }
                else
                {
                    use->setChecked(false);
                    unuse->setChecked(true);
                }

                ContextMenu.exec(QCursor::pos());
            }
        }


    }
}

void GraphicsScene::setEditingMode(modes selected_mode)
{
   editingMode = selected_mode;
}

void GraphicsScene::setSelectedId(int id)
{
    rect_item_list.id(selected_Item, id);
}

void GraphicsScene::redrawRect(int id)
{
    if( rect_item_list.at(id) != selected_Item)
    {
        if( rect_item_list.used(id) != true )
        {
            QBrush brush( QColor(200,200,250,150) ,  Qt::SolidPattern);
            QPen pen(Qt::cyan, 0);
            pen.setStyle(Qt::SolidLine);
            rect_item_list.at(id)->setPen(pen);
            rect_item_list.at(id)->setBrush(brush);
        }
        else
        {
            QBrush brush( QColor(0, 0, 255, 150) ,  Qt::Dense5Pattern);
            QPen pen(Qt::cyan, 0);
            pen.setStyle(Qt::SolidLine);
            rect_item_list.at(id)->setPen(pen);
            rect_item_list.at(id)->setBrush(brush);
        }
    }
}


void GraphicsScene::useClicked()
{
    rect_item_list.used( rect_item_list.id( (QGraphicsRectItem*)itemAt( last_mouseup_pos ) ) , true);
    redrawRect(rect_item_list.id( (QGraphicsRectItem*)itemAt( last_mouseup_pos ) ));
    emit rectStateChanged(rect_item_list.id( (QGraphicsRectItem*)itemAt( last_mouseup_pos ) ), true);
}

void GraphicsScene::unuseClicked()
{
    rect_item_list.used( rect_item_list.id( (QGraphicsRectItem*)itemAt( last_mouseup_pos ) ) , false);
    redrawRect(rect_item_list.id( (QGraphicsRectItem*)itemAt( last_mouseup_pos ) ));
    emit rectStateChanged(rect_item_list.id( (QGraphicsRectItem*)itemAt( last_mouseup_pos ) ), false);
}



}// namespace verema
